/******************************************************************************
 *
 * MotionViewer
 * Copyright (C) 2007 Sangyoon Lee, Electronic Visualization Laboratory, 
 * University of Illinois at Chicago
 *
 * This software is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either Version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 * 
 * You should have received a copy of the GNU Lesser Public License along
 * with this software; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Questions or comments about MotionViewer should be directed to 
 * cavern@evl.uic.edu
 *
 * Original source code from Ogre File Dialog Example
 * Refer to http://www.ogre3d.org/wiki/index.php/CEGUICommonFileDialog
 * Minor modification for mac porting
 *****************************************************************************/

#ifndef _CEGUI_SINGLETON_X_H_
#define _CEGUI_SINGLETON_X_H_

#if defined(_MSC_VER)
#	pragma warning(push)
#	pragma warning(disable : 4786)
#endif

namespace CEGUI
{
	/*************************************************************************
		Class: CEGUISingletonX
		Alternative for the existing CEGUI Singleton class. This one doesn't
		require the Singleton to be explicitly instantiated by 'new'.
	*************************************************************************/
	template<class T>
	class CEGUISingletonX
	{
		private:
			class _InstPtr
			{
				public:
					_InstPtr() : m_ptr(0) {}
					~_InstPtr() { delete m_ptr; }
					T* get() { return m_ptr; }
					void Set(T* p)
					{
			            if(p!= 0)
					    {
							delete m_ptr;
			                m_ptr = p;
					    }
			        }
			    private:
					T* m_ptr;
			};

			static _InstPtr sm_ptr;
			CEGUISingletonX();
			CEGUISingletonX(const CEGUISingletonX&);
			CEGUISingletonX& operator=(const CEGUISingletonX&);

		public:
			static T& getSingleton()
			{
				if(sm_ptr.get() == 0)
				{
		            sm_ptr.Set(new T());
		        }
				return *sm_ptr.get();
			}

			static T* getSingletonPtr()
			{
				if(sm_ptr.get() == 0)
				{
		            sm_ptr.Set(new T());
		        }
				return sm_ptr.get();
			}
	};
	
	template <class T>
	typename CEGUISingletonX<T>::_InstPtr CEGUISingletonX<T>::sm_ptr;
}
#endif

